const fs = require('fs');
const path = require('path');
const ApiError = require('../utils/ApiError');
const submissionModel = require('../models/submission.model');
const experimentModel = require('../models/experiment.model');
const userModel = require('../models/user.model');

// 文件上传配置
const UPLOAD_DIR = path.resolve(__dirname, '../uploads/submissions');
const MAX_FILE_SIZE = 50 * 1024 * 1024; // 50MB
const MAX_FILES = 5;

// 确保上传目录存在
if (!fs.existsSync(UPLOAD_DIR)) {
    fs.mkdirSync(UPLOAD_DIR, { recursive: true });
}

// 处理文件上传
const handleFileUpload = (file, studentId, experimentId) => {
    // 验证文件大小
    if (file.size > MAX_FILE_SIZE) {
        throw new ApiError(400, `文件 ${file.originalname} 超过 ${MAX_FILE_SIZE / (1024 * 1024)}MB 大小限制`);
    }
    
    // 创建目标目录：uploads/submissions/studentId/experimentId/
    const studentDir = path.join(UPLOAD_DIR, studentId);
    const expDir = path.join(studentDir, experimentId);
    
    if (!fs.existsSync(expDir)) {
        fs.mkdirSync(expDir, { recursive: true });
    }
    
    // 生成唯一文件名
    const timestamp = Date.now();
    const ext = path.extname(file.originalname);
    const filename = `${timestamp}-${file.originalname}`;
    const filePath = path.join(expDir, filename);
    
    // 保存文件
    fs.writeFileSync(filePath, file.buffer);
    
    return {
        originalName: file.originalname,
        savedName: filename,
        path: filePath,
        size: file.size,
        mimetype: file.mimetype
    };
};

// 提交实验
exports.submitExperiment = async (req, res) => {
    try {
        console.log('处理实验提交请求');
        
        // 从认证信息中获取学生ID
        const studentId = req.user.id;
        const { experimentId } = req.body;
        const files = req.files || [];
        
        // 验证文件数量
        if (files.length > MAX_FILES) {
            throw new ApiError(400, `最多只能上传 ${MAX_FILES} 个文件`);
        }
        
        // 验证用户
        const student = await userModel.findStudentById(studentId);
        if (!student) {
            console.warn(`学生未找到 ID: ${studentId}`);
            throw new ApiError(404, '学生未找到');
        }
        
        // 验证实验
        /*const experiment = await experimentModel.getExperimentById(experimentId);
        if (!experiment) {
            console.warn(`实验未找到 ID: ${experimentId}`);
            throw new ApiError(404, '实验未找到');
        }*/
        
        // 处理文件上传
        const uploadedFiles = files.map(file => 
            handleFileUpload(file, studentId, experimentId)
        );
        
        // 创建提交记录
        const submission = await submissionModel.createSubmission({
            studentId,
            experimentId,
            files: uploadedFiles
        });
        
        console.log(`学生 ${studentId} 提交实验 ${experimentId} 成功`);
        
        res.status(201).json({
            status: 'success',
            message: '文件提交成功',
            data: submission
        });
    } catch (err) {
        console.error('提交实验失败:', err.message);
        
        if (err instanceof ApiError) {
            res.status(err.statusCode).json({ 
                status: 'error', 
                message: err.message 
            });
        } else {
            res.status(500).json({ 
                status: 'error', 
                message: '服务器内部错误' 
            });
        }
    }
};

// 获取学生提交记录
exports.getStudentSubmissions = async (req, res) => {
    try {
        console.log(`获取学生提交记录 ID: ${req.params.studentId}`);
        
        const { studentId } = req.params;
        
        // 验证学生
        const student = await userModel.findStudentById(studentId);
        if (!student) {
            console.warn(`学生未找到 ID: ${studentId}`);
            throw new ApiError(404, '学生未找到');
        }
        
        // 获取提交记录
        const submissions = await submissionModel.getSubmissionsByStudentId(studentId);
        
        res.json({
            status: 'success',
            data: submissions
        });
    } catch (err) {
        console.error('获取学生提交记录失败:', err.message);
        
        if (err instanceof ApiError) {
            res.status(err.statusCode).json({ 
                status: 'error', 
                message: err.message 
            });
        } else {
            res.status(500).json({ 
                status: 'error', 
                message: '服务器内部错误' 
            });
        }
    }
};

// 下载提交文件
exports.downloadSubmissionFile = async (req, res) => {
    try {
        const { submissionId, fileId } = req.params;
        console.log(`下载提交文件 提交ID: ${submissionId}, 文件ID: ${fileId}`);
        
        // 获取提交记录
        const submission = await submissionModel.getSubmissionById(submissionId);
        const file = submission.files.find(f => f.id === fileId);
        
        if (!file) {
            console.warn(`文件未找到 提交ID: ${submissionId}, 文件ID: ${fileId}`);
            throw new ApiError(404, '文件未找到');
        }
        
        // 验证文件存在
        if (!fs.existsSync(file.path)) {
            console.error(`文件不存在: ${file.path}`);
            throw new ApiError(404, '文件不存在');
        }
        
        // 设置响应头
        res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(file.originalName)}"`);
        res.setHeader('Content-Type', file.mimetype);
        console.log(`开始下载: ${file.originalName}`);
        
        // 创建可读流并传输文件
        const fileStream = fs.createReadStream(file.path);
        fileStream.pipe(res);
        
        // 处理错误
        fileStream.on('error', (err) => {
            console.error(`文件流错误: ${err.message}`);
            if (!res.headersSent) {
                res.status(500).json({ message: '文件传输错误' });
            }
        });
    } catch (err) {
        console.error('下载提交文件失败:', err.message);
        
        if (err instanceof ApiError) {
            res.status(err.statusCode).json({ 
                status: 'error', 
                message: err.message 
            });
        } else {
            res.status(500).json({ 
                status: 'error', 
                message: '服务器内部错误' 
            });
        }
    }
};

// 评分提交
exports.gradeSubmission = async (req, res) => {
    try {
        const { submissionId } = req.params;
        const { grade, feedback } = req.body;
        console.log(`评分提交记录 ID: ${submissionId}`);
        
        // 验证分数
        if (grade === undefined || grade < 0 || grade > 100) {
            throw new ApiError(400, '分数必须在0-100之间');
        }
        
        // 更新提交记录
        const submission = await submissionModel.gradeSubmission(submissionId, grade, feedback);
        
        res.json({
            status: 'success',
            message: '提交评分成功',
            data: submission
        });
    } catch (err) {
        console.error('评分提交失败:', err.message);
        
        if (err instanceof ApiError) {
            res.status(err.statusCode).json({ 
                status: 'error', 
                message: err.message 
            });
        } else {
            res.status(500).json({ 
                status: 'error', 
                message: '服务器内部错误' 
            });
        }
    }
};